package com.ruoyi.system.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.Counts;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.system.domain.ExamPaperAnswerItemObject;
import com.ruoyi.system.domain.ExamPaperAnswerObject;
import com.ruoyi.system.domain.QuestionItemObject;
import com.ruoyi.system.domain.SysExamPaperAnswer;
import com.ruoyi.system.domain.wx.PaperTypeStatisticsVo;
import com.ruoyi.system.domain.wx.SchoolStatisticsVo;
import com.ruoyi.system.mapper.SysExamPaperAnswerMapper;
import com.ruoyi.system.service.ISysExamPaperAnswerService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * 试卷答案Service业务层处理
 *
 * @author ruoyi
 * @date 2025-09-18
 */
@Service
@RequiredArgsConstructor
public class SysExamPaperAnswerServiceImpl extends ServiceImpl<SysExamPaperAnswerMapper, SysExamPaperAnswer> implements ISysExamPaperAnswerService {
    private final SysExamPaperAnswerMapper sysExamPaperAnswerMapper;

    @Override
    public int submit(ExamPaperAnswerObject examPaperAnswerObject) {
        Optional.ofNullable(sysExamPaperAnswerMapper.selectByOpenIdAndExamPaperId(examPaperAnswerObject))
                .ifPresent(sysExamPaperAnswer -> {
                    throw new ServiceException("该用户已提交过答案");
                });
        List<ExamPaperAnswerItemObject> frameTextContent = getFrameTextContent(examPaperAnswerObject.getFrameTextContent());
        Long systemScore = 0L;
        for (ExamPaperAnswerItemObject itemObject : frameTextContent) {
            List<QuestionItemObject> options = itemObject.getOptions();
            for (QuestionItemObject option : options) {
                List<String> list = Arrays.asList(itemObject.getSelectedAnswer().split(","));
                if (list.contains(option.getPrefix())) {
                    systemScore += option.getScore();
                }
            }
        }
        SysExamPaperAnswer sysExamPaperAnswer = new SysExamPaperAnswer();
        sysExamPaperAnswer.setScore(systemScore);
        sysExamPaperAnswer.setPhone(examPaperAnswerObject.getPhone());
        sysExamPaperAnswer.setOpenId(examPaperAnswerObject.getOpenid());
        sysExamPaperAnswer.setFrameTextContent(frameTextContent);
        sysExamPaperAnswer.setName(examPaperAnswerObject.getName());
        sysExamPaperAnswer.setTitle(examPaperAnswerObject.getTitle());
        sysExamPaperAnswer.setSchool(examPaperAnswerObject.getSchool());
        sysExamPaperAnswer.setExamPaperId(examPaperAnswerObject.getExamPaperId());
        sysExamPaperAnswer.setQuestionCount(examPaperAnswerObject.getQuestionCount());
        return sysExamPaperAnswerMapper.insert(sysExamPaperAnswer);
    }

    @Override
    public int whetherSubmit(ExamPaperAnswerObject examPaperAnswerObject) {
        Optional.ofNullable(sysExamPaperAnswerMapper.selectByOpenIdAndExamPaperId(examPaperAnswerObject))
                .ifPresent(sysExamPaperAnswer -> {
                    throw new ServiceException("该用户已提交过答案");
                });
        return 1;
    }

    @Override
    public List<SysExamPaperAnswer> selectSysExamPaperAnswerList(SysExamPaperAnswer sysExamPaperAnswer) {
        return sysExamPaperAnswerMapper.selectSysExamPaperAnswerList(sysExamPaperAnswer);
    }


    // 查询试卷的题目分类统计情况
    @Override
    public Map<String, Object> getExamPaperTypeStatistics(Long examPaperId) {
        Map<String, Object> map = new HashMap<>(2);
        List<SysExamPaperAnswer> sysExamPaperAnswersList = sysExamPaperAnswerMapper.selectSysExamPaperById(examPaperId);
        List<ExamPaperAnswerItemObject> examPaperAnswerItemObjectList = sysExamPaperAnswersList.stream()
                .map(SysExamPaperAnswer::getFrameTextContent)
                .flatMap(Collection::stream)
                .collect(Collectors.toList());

        List<ExamPaperAnswerItemObject> list = getFrameTextContent(examPaperAnswerItemObjectList);
        List<SysDictData> questionClassification = DictUtils.getDictCache("question_classification");
        // 根据 questionIndex 分组，计算每一题的总分
        Map<Long, Long> questionScoreMap = list.stream()
                .collect(Collectors.groupingBy(
                        ExamPaperAnswerItemObject::getQuestionIndex,
                        Collectors.summingLong(item -> {
                            // 计算每个答题项的得分
                            if (item.getOptions() == null || item.getSelectedAnswer() == null) {
                                return 0L;
                            }
                            // 将选中的答案转换为列表
                            List<String> selectedAnswers = Arrays.asList(item.getSelectedAnswer().split(","));
                            // 计算该答题项的总得分
                            return item.getOptions().stream()
                                    .filter(option -> selectedAnswers.contains(option.getPrefix()))
                                    .mapToLong(option -> option.getScore() != null ? option.getScore() : 0L)
                                    .sum();
                        })
                ));

        // 转换为 List<PaperTypeStatisticsVo> 格式
        List<PaperTypeStatisticsVo> questionScoreStatistics = questionScoreMap.entrySet().stream()
                .sorted(Map.Entry.comparingByKey())
                .map(entry -> PaperTypeStatisticsVo.builder()
                        .range("第" + entry.getKey() + "题")  // range 表示题目序号
                        .count(entry.getValue())              // count 表示总分
                        .build())
                .collect(Collectors.toList());
        // 输出每一题的总分统计
        System.out.println("=== 每一题的总分统计 ===");
        questionScoreStatistics.forEach(stat -> {
            System.out.println("题目: " + stat.getRange() + ", 总分: " + stat.getCount());
        });
        // 将结果添加到返回的map中
        map.put("questionScoreStatistics", questionScoreStatistics);

        // 根据 questionClassification 分组统计
        Map<String, List<ExamPaperAnswerItemObject>> classificationGroupMap = list.stream()
                .collect(Collectors.groupingBy(
                        item -> item.getQuestionClassification() != null ? item.getQuestionClassification() : "未分类"
                ));

        // 转换为 List<PaperTypeStatisticsVo> 格式
        List<PaperTypeStatisticsVo> classificationStatistics = classificationGroupMap.entrySet().stream()
                .map(entry -> {
                    String classification = entry.getKey();
                    List<ExamPaperAnswerItemObject> items = entry.getValue();

                    // 计算该分类的题目数量
                    long questionCount = items.size();

                    // 计算该分类的总分
                    long totalScore = items.stream()
                            .mapToLong(item -> {
                                if (item.getOptions() == null || item.getSelectedAnswer() == null) {
                                    return 0L;
                                }

                                // 将选中的答案转换为列表
                                List<String> selectedAnswers = Arrays.asList(item.getSelectedAnswer().split(","));

                                // 计算该答题项的总得分
                                return item.getOptions().stream()
                                        .filter(option -> selectedAnswers.contains(option.getPrefix()))
                                        .mapToLong(option -> option.getScore() != null ? option.getScore() : 0L)
                                        .sum();
                            })
                            .sum();

                    // 根据字典数据获取分类名称
                    String classificationName = classification;
                    if (questionClassification != null) {
                        classificationName = questionClassification.stream()
                                .filter(dict -> classification.equals(dict.getDictValue()))
                                .map(dict -> dict.getDictLabel())
                                .findFirst()
                                .orElse(classification);
                    }

                    return PaperTypeStatisticsVo.builder()
                            .name(classificationName)        // name 分组名称
                            .count(questionCount)            // count 每组题目数量
                            .totalScore(totalScore)          // totalScore 每组总分
                            .build();
                })
                .sorted((a, b) -> a.getName().compareTo(b.getName()))  // 按名称排序
                .collect(Collectors.toList());
        // 输出题目分类统计
        System.out.println("=== 题目分类统计 ===");
        classificationStatistics.forEach(stat -> {
            System.out.println("分类: " + stat.getName() +
                    ", 题目数量: " + stat.getCount() +
                    ", 总分: " + stat.getTotalScore());
        });
        // 将结果添加到返回的map中
        map.put("classificationStatistics", classificationStatistics);
        return map;
    }

    @Override
    public Map<String, Object> getExamPaperTypeStatistics(ExamPaperAnswerObject examPaperAnswerObject) {
        Map<String, Object> map = new HashMap<>(2);
        SysExamPaperAnswer sysExamPaperAnswer = new SysExamPaperAnswer();
        sysExamPaperAnswer.setExamPaperId(examPaperAnswerObject.getExamPaperId());
        sysExamPaperAnswer.setSchool(examPaperAnswerObject.getSchool());
        sysExamPaperAnswer.setName(examPaperAnswerObject.getName());
        sysExamPaperAnswer.setPhone(examPaperAnswerObject.getPhone());
        List<SysExamPaperAnswer> sysExamPaperAnswersList = sysExamPaperAnswerMapper.selectSysExamPaperAnswerList(sysExamPaperAnswer);
        List<ExamPaperAnswerItemObject> examPaperAnswerItemObjectList = sysExamPaperAnswersList
                .stream()
                .map(SysExamPaperAnswer::getFrameTextContent)
                .flatMap(Collection::stream)
                .collect(Collectors.toList());
        List<ExamPaperAnswerItemObject> list = getFrameTextContent(examPaperAnswerItemObjectList);
        List<SysDictData> questionClassification = DictUtils.getDictCache("question_classification");
        // 根据 questionIndex 分组，计算每一题的总分
        Map<Long, Long> questionScoreMap = list.stream()
                .collect(Collectors.groupingBy(
                        ExamPaperAnswerItemObject::getQuestionIndex,
                        Collectors.summingLong(item -> {
                            // 计算每个答题项的得分
                            if (item.getOptions() == null || item.getSelectedAnswer() == null) {
                                return 0L;
                            }
                            // 将选中的答案转换为列表
                            List<String> selectedAnswers = Arrays.asList(item.getSelectedAnswer().split(","));
                            // 计算该答题项的总得分
                            return item.getOptions().stream()
                                    .filter(option -> selectedAnswers.contains(option.getPrefix()))
                                    .mapToLong(option -> option.getScore() != null ? option.getScore() : 0L)
                                    .sum();
                        })
                ));

        // 转换为 List<PaperTypeStatisticsVo> 格式
        List<PaperTypeStatisticsVo> questionScoreStatistics = questionScoreMap.entrySet().stream()
                .sorted(Map.Entry.comparingByKey())
                .map(entry -> PaperTypeStatisticsVo.builder()
                        .range("第" + entry.getKey() + "题")  // range 表示题目序号
                        .count(entry.getValue())              // count 表示总分
                        .build())
                .collect(Collectors.toList());
        // 输出每一题的总分统计
        System.out.println("=== 每一题的总分统计 ===");
        questionScoreStatistics.forEach(stat -> {
            System.out.println("题目: " + stat.getRange() + ", 总分: " + stat.getCount());
        });
        // 将结果添加到返回的map中
        map.put("questionScoreStatistics", questionScoreStatistics);

        // 根据 questionClassification 分组统计
        Map<String, List<ExamPaperAnswerItemObject>> classificationGroupMap = list.stream()
                .collect(Collectors.groupingBy(
                        item -> item.getQuestionClassification() != null ? item.getQuestionClassification() : "未分类"
                ));

        // 转换为 List<PaperTypeStatisticsVo> 格式
        List<PaperTypeStatisticsVo> classificationStatistics = classificationGroupMap.entrySet().stream()
                .map(entry -> {
                    String classification = entry.getKey();
                    List<ExamPaperAnswerItemObject> items = entry.getValue();

                    // 计算该分类的题目数量
                    long questionCount = items.size();

                    // 计算该分类的总分
                    long totalScore = items.stream()
                            .mapToLong(item -> {
                                if (item.getOptions() == null || item.getSelectedAnswer() == null) {
                                    return 0L;
                                }

                                // 将选中的答案转换为列表
                                List<String> selectedAnswers = Arrays.asList(item.getSelectedAnswer().split(","));

                                // 计算该答题项的总得分
                                return item.getOptions().stream()
                                        .filter(option -> selectedAnswers.contains(option.getPrefix()))
                                        .mapToLong(option -> option.getScore() != null ? option.getScore() : 0L)
                                        .sum();
                            })
                            .sum();

                    // 根据字典数据获取分类名称
                    String classificationName = classification;
                    if (questionClassification != null) {
                        classificationName = questionClassification.stream()
                                .filter(dict -> classification.equals(dict.getDictValue()))
                                .map(dict -> dict.getDictLabel())
                                .findFirst()
                                .orElse(classification);
                    }
                    return PaperTypeStatisticsVo.builder()
                            .name(classificationName)        // name 分组名称
                            .count(questionCount)            // count 每组题目数量
                            .totalScore(totalScore)          // totalScore 每组总分
                            .build();
                })
                .sorted((a, b) -> a.getName().compareTo(b.getName()))  // 按名称排序
                .collect(Collectors.toList());
        // 输出题目分类统计
        System.out.println("=== 题目分类统计 ===");
        classificationStatistics.forEach(stat -> {
            System.out.println("分类: " + stat.getName() +
                    ", 题目数量: " + stat.getCount() +
                    ", 总分: " + stat.getTotalScore());
        });
        // 将结果添加到返回的map中
        map.put("classificationStatistics", classificationStatistics);
        return map;
    }

    // 用户填写信息List
    @Override
    public List<SysExamPaperAnswer> statisticsList(SysExamPaperAnswer sysExamPaperAnswer) {
        List<SysDictData> questionClassification = DictUtils.getDictCache("question_classification");
        List<SysExamPaperAnswer> sysExamPaperAnswersList = sysExamPaperAnswerMapper.selectSysExamPaperAnswerList(sysExamPaperAnswer);
        for (SysExamPaperAnswer examPaperAnswer : sysExamPaperAnswersList) {
            List<ExamPaperAnswerItemObject> list = getFrameTextContent(examPaperAnswer.getFrameTextContent());
            // 根据 questionClassification 分组统计
            Map<String, List<ExamPaperAnswerItemObject>> classificationGroupMap = list.stream()
                    .collect(Collectors.groupingBy(item -> item.getQuestionClassification() != null ? item.getQuestionClassification() : "未分类"));
            // 转换为 List<PaperTypeStatisticsVo> 格式
            List<PaperTypeStatisticsVo> classificationStatistics = classificationGroupMap.entrySet()
                    .stream()
                    .map(entry -> {
                        String classification = entry.getKey();
                        List<ExamPaperAnswerItemObject> items = entry.getValue();
                        // 计算该分类的题目数量
                        long questionCount = items.size();

                        // 计算该分类的总分
                        long totalScore = items.stream()
                                .mapToLong(item -> {
                                    if (item.getOptions() == null || item.getSelectedAnswer() == null) {
                                        return 0L;
                                    }
                                    // 将选中的答案转换为列表
                                    List<String> selectedAnswers = Arrays.asList(item.getSelectedAnswer().split(","));

                                    // 计算该答题项的总得分
                                    return item.getOptions().stream()
                                            .filter(option -> selectedAnswers.contains(option.getPrefix()))
                                            .mapToLong(option -> option.getScore() != null ? option.getScore() : 0L)
                                            .sum();
                                })
                                .sum();

                        // 根据字典数据获取分类名称
                        String classificationName = classification;
                        if (questionClassification != null) {
                            classificationName = questionClassification.stream()
                                    .filter(dict -> classification.equals(dict.getDictValue()))
                                    .map(dict -> dict.getDictLabel())
                                    .findFirst()
                                    .orElse(classification);
                        }
                        return PaperTypeStatisticsVo.builder()
                                .name(classificationName)        // name 分组名称
                                .count(questionCount)            // count 每组题目数量
                                .totalScore(totalScore)          // totalScore 每组总分
                                .build();
                    })
                    .sorted((a, b) -> a.getName().compareTo(b.getName()))  // 按名称排序
                    .collect(Collectors.toList());
            // 输出题目分类统计
            System.out.println("=== 题目分类统计 ===");
            classificationStatistics.forEach(stat -> {
                System.out.println("分类: " + stat.getName() +
                        ", 题目数量: " + stat.getCount() +
                        ", 总分: " + stat.getTotalScore());
            });
            examPaperAnswer.setClassificationStatistics(classificationStatistics);
        }
        return sysExamPaperAnswersList;
    }

    @Override
    public List<SchoolStatisticsVo> statisticsSchoolList(SysExamPaperAnswer sysExamPaperAnswer) {
        List<SysDictData> questionClassification = DictUtils.getDictCache("question_classification");
        List<String> schoolNames = sysExamPaperAnswerMapper.selectDistinctSchool(sysExamPaperAnswer.getSchool());
        List<SchoolStatisticsVo> schoolStatisticsVoList = new ArrayList<>();
        for (String schoolName : schoolNames) {
            AtomicReference<Long> count = new AtomicReference<>(0L);
            AtomicReference<Long> score = new AtomicReference<>(0L);
            SchoolStatisticsVo schoolStatisticsVo = new SchoolStatisticsVo();
            schoolStatisticsVo.setSchool(schoolName);
            SysExamPaperAnswer answer = new SysExamPaperAnswer();
            answer.setSchool(schoolName);
            List<SysExamPaperAnswer> sysExamPaperAnswersList = sysExamPaperAnswerMapper.selectSysExamPaperAnswerList(answer);
            List<ExamPaperAnswerItemObject> examPaperAnswerItemObjectList = sysExamPaperAnswersList
                    .stream()
                    .map(SysExamPaperAnswer::getFrameTextContent)
                    .flatMap(Collection::stream)
                    .collect(Collectors.toList());
            List<ExamPaperAnswerItemObject> list = getFrameTextContent(examPaperAnswerItemObjectList);
            // 根据 questionClassification 分组统计
            Map<String, List<ExamPaperAnswerItemObject>> classificationGroupMap = list.stream()
                    .collect(Collectors.groupingBy(item -> item.getQuestionClassification() != null ? item.getQuestionClassification() : "未分类"));
            // 转换为 List<PaperTypeStatisticsVo> 格式
            List<PaperTypeStatisticsVo> classificationStatistics = classificationGroupMap.entrySet()
                    .stream()
                    .map(entry -> {
                        String classification = entry.getKey();
                        List<ExamPaperAnswerItemObject> items = entry.getValue();
                        // 计算该分类的题目数量
                        long questionCount = items.size();
                        count.updateAndGet(v -> v + questionCount);
                        // 计算该分类的总分
                        long totalScore = items.stream()
                                .mapToLong(item -> {
                                    if (item.getOptions() == null || item.getSelectedAnswer() == null) {
                                        return 0L;
                                    }
                                    // 将选中的答案转换为列表
                                    List<String> selectedAnswers = Arrays.asList(item.getSelectedAnswer().split(","));

                                    // 计算该答题项的总得分
                                    return item.getOptions().stream()
                                            .filter(option -> selectedAnswers.contains(option.getPrefix()))
                                            .mapToLong(option -> option.getScore() != null ? option.getScore() : 0L)
                                            .sum();
                                })
                                .sum();
                        score.updateAndGet(v -> v + totalScore);
                        // 根据字典数据获取分类名称
                        String classificationName = classification;
                        if (questionClassification != null) {
                            classificationName = questionClassification.stream()
                                    .filter(dict -> classification.equals(dict.getDictValue()))
                                    .map(dict -> dict.getDictLabel())
                                    .findFirst()
                                    .orElse(classification);
                        }
                        return PaperTypeStatisticsVo.builder()
                                .name(classificationName)        // name 分组名称
                                .count(questionCount)            // count 每组题目数量
                                .totalScore(totalScore)          // totalScore 每组总分
                                .build();
                    })
                    .sorted((a, b) -> a.getName().compareTo(b.getName()))  // 按名称排序
                    .collect(Collectors.toList());
            // 输出题目分类统计
            System.out.println("=== 题目分类统计 ===");
            classificationStatistics.forEach(stat -> {
                System.out.println("分类: " + stat.getName() +
                        ", 题目数量: " + stat.getCount() +
                        ", 总分: " + stat.getTotalScore());
            });
            schoolStatisticsVo.setQuestionCount(count.get());
            schoolStatisticsVo.setTotalScore(score.get());
            schoolStatisticsVo.setClassificationStatistics(classificationStatistics);
            schoolStatisticsVoList.add(schoolStatisticsVo);
        }
        return schoolStatisticsVoList;
    }

    public List<ExamPaperAnswerItemObject> getFrameTextContent(List<ExamPaperAnswerItemObject> objects) {
        if (objects == null || objects.isEmpty()) {
            return new ArrayList<>();
        }
        Object first = objects.get(0);
        if (first instanceof ExamPaperAnswerItemObject) {
            // 已是强类型集合，直接返回（或浅拷贝）
            return objects;
        }
        // 处理 MyBatis/Jackson 映射为 LinkedHashMap 等非强类型的情况，避免 JSON 轮转
        java.util.List<ExamPaperAnswerItemObject> list = new java.util.ArrayList<>(objects.size());
        com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();
        for (Object obj : objects) {
            if (obj instanceof ExamPaperAnswerItemObject) {
                list.add((ExamPaperAnswerItemObject) obj);
            } else {
                ExamPaperAnswerItemObject examPaperAnswerItemObject = mapper.convertValue(obj, ExamPaperAnswerItemObject.class);
                list.add(examPaperAnswerItemObject);
            }
        }
        return list;
    }





}
